package internal

import (
	"sort"
	"sync"

	log "github.com/sirupsen/logrus"

	"GameServer/Game/dbmodule"
	"GameServer/Game/m"
)

const Union_Limit = 120
const User_Limit = 120

type Rank struct {
	UnionRanks []*m.UnionRank
	UserRanks  []*m.UserRank

	MUnion map[string]int64
	MUser  map[string]int64

	unionRwLock sync.RWMutex
	userRwLock  sync.RWMutex
}

func NewRank() *Rank {
	return &Rank{
		UnionRanks: make([]*m.UnionRank, 0),
		UserRanks:  make([]*m.UserRank, 0),
		MUnion:     make(map[string]int64),
		MUser:      make(map[string]int64),
	}
}

func (r *Rank) GetUnionRank() []*m.UnionRank {
	r.unionRwLock.RLock()
	defer r.unionRwLock.RUnlock()
	ur := make([]*m.UnionRank, 0)
	for _, item := range r.UnionRanks {
		ur = append(ur, item)
	}
	return ur
}

func (r *Rank) GetUserRank() []*m.UserRank {
	r.userRwLock.RLock()
	defer r.userRwLock.RUnlock()
	ur := make([]*m.UserRank, 0)
	for _, item := range r.UserRanks {
		ur = append(ur, item)
	}
	return ur
}

// 添加公会排行榜
func (r *Rank) AddUnionRank(union *m.Union) {
	r.unionRwLock.Lock()
	defer r.unionRwLock.Unlock()
	mUnionRank := &m.UnionRank{
		UnionId:   union.Id.Hex(),
		Name:      union.Name,
		ShortName: union.ShortName,
		Star:      union.Star,
		Ico:       union.Ico,
	}
	if len(r.UnionRanks) == 0 {
		mUnionRank.RankId = 1
		r.UnionRanks = append(r.UnionRanks, mUnionRank)
		return
	}

	if len(r.UnionRanks) >= Union_Limit {
		lastUnionRank := r.UnionRanks[len(r.UnionRanks)-1]
		if mUnionRank.Star < lastUnionRank.Star {
			return
		}
	}
	list := make([]*m.UnionRank, 0)
	// 过滤自己
	for _, item := range r.UnionRanks {
		if item.UnionId == mUnionRank.UnionId {
			continue
		}
		list = append(list, item)
	}

	index := int64(0)
	flag := false
	r.UnionRanks = make([]*m.UnionRank, 0)

	for _, item := range list {
		if item.Star < mUnionRank.Star && !flag {
			mUnionRank.RankId = index
			r.UnionRanks = append(r.UnionRanks, mUnionRank)
			flag = true
			index++
		}

		if index >= Union_Limit {
			return
		}

		item.RankId = index
		r.UnionRanks = append(r.UnionRanks, item)
		index++
	}

	if !flag {
		mUnionRank.RankId = index
		r.UnionRanks = append(r.UnionRanks, mUnionRank)
	}
}

// 添加用户排行榜
func (r *Rank) AddUserRank(user *m.User) {
	r.userRwLock.Lock()
	defer r.userRwLock.Unlock()
	mUserRank := &m.UserRank{
		Uid:  user.Uid.Hex(),
		Name: user.Name,
		Head: user.Head,
		// Star:        user.StarSum,
		Star:        user.StarVal(),
		AvatarFrame: user.AvatarFrame,
	}
	if len(r.UserRanks) == 0 {
		mUserRank.RankId = 1
		r.UserRanks = append(r.UserRanks, mUserRank)
		return
	}

	if len(r.UserRanks) >= User_Limit {
		lastUserRank := r.UserRanks[len(r.UserRanks)-1]
		if mUserRank.Star < lastUserRank.Star {
			return
		}
	}
	list := make([]*m.UserRank, 0)
	// 过滤自己
	for _, item := range r.UserRanks {
		if item.Uid == mUserRank.Uid {
			continue
		}
		list = append(list, item)
	}

	flag := false
	r.UserRanks = make([]*m.UserRank, 0)

	index := int64(0)
	for _, item := range list {
		if item.Star < mUserRank.Star && !flag {
			mUserRank.RankId = index
			r.UserRanks = append(r.UserRanks, mUserRank)
			flag = true
			index++
		}

		if index >= User_Limit {
			return
		}

		item.RankId = index
		r.UserRanks = append(r.UserRanks, item)
		index++
	}

	if !flag {
		mUserRank.RankId = index
		r.UserRanks = append(r.UserRanks, mUserRank)
	}
}

// 排行榜初始化
func (rank *Rank) Init() {

	// 玩家排名
	users := make([]*m.User, 0)
	// err := dbmodule.MgoDB.GameDB.FindAllSortLimit("user", nil, nil, &users, []string{"-starSum", "starChangeTime"}, 120)
	err := dbmodule.MgoDB.GameDB.FindAll("user", nil, nil, &users)
	if err != nil {
		log.Error("RankSort获取用户数据失败：", err)
		return
	}
	for _, item := range users {
		item.StarSum = item.StarVal()
	}

	sort.Slice(users, func(i, j int) bool {
		return users[i].StarSum > users[j].StarSum
	})

	for i, item := range users {
		if i >= User_Limit {
			break
		}
		ur := &m.UserRank{
			RankId:      int64(i),
			Uid:         item.Uid.Hex(),
			Name:        item.Name,
			Head:        item.Head,
			Star:        item.StarSum,
			AvatarFrame: item.AvatarFrame,
		}
		rank.UserRanks = append(rank.UserRanks, ur)
		rank.MUser[ur.Uid] = int64(i)
	}

	// 工会排名
	unions := make([]*m.Union, 0)
	// err = dbmodule.MgoDB.GameDB.FindAllSortLimit("union", nil, nil, &unions, []string{"-star", "starChangeTime"}, 1020)
	err = dbmodule.MgoDB.GameDB.FindAll("union", nil, nil, &unions)
	if err != nil {
		log.Error("RankSort获取公会数据失败：", err)
		return
	}

	sort.Slice(unions, func(i, j int) bool {
		return unions[i].Star > unions[j].Star
	})

	for i, item := range unions {
		if i >= Union_Limit {
			break
		}
		ur := &m.UnionRank{
			RankId:    int64(i),
			UnionId:   item.Id.Hex(),
			Name:      item.Name,
			ShortName: item.ShortName,
			Star:      item.Star,
			Ico:       item.Ico,
		}
		rank.UnionRanks = append(rank.UnionRanks, ur)
		rank.MUnion[ur.UnionId] = int64(i)
	}
}

func (r *Rank) Run(closeSig chan bool) {

}

func (r *Rank) Destroy() {

}
